LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

Servlet_Jsp基础与进阶+JSTL\EL表达式

2022/9/5 后端

单机时代

联机时代(Client-Server模式) [微信+支付宝+QQ] [需安装APP]

  • Client/Server结构(C/S结构)是指客户端服务器结构

互联网时代(Browser-Server模式) [百度+淘宝+火车票系统]

  • Browser-Server模式(B/S模式)即浏览器服务器架构模式
请求与响应 [成对出现]
  • 从浏览器发出送给服务器的数据包成为”请求(Request)
  • 从服务器返回给浏览器的结果称为”响应(Response)
J2EE
  • J2EE(Java 2 Platform Enterprise Edition)是指”Java 2企业版”
  • **开发BS(Web)**应用程序就是J2EE最核心的功能
  • J2EE由13个功能模块组成

Apache Tomcat
  • Tomcat是Apache旗下免费的开放源代码的Web应用服务器程序
J2EE与Tomcat的关系
  • J2EE是一组技术规范与指南
  • Tomcat是J2EE Web (Servlet与JSP) 标准的实现者
  • J2SE是J2EE运行的基石,运行Tomcat离不开J2SE
Servlet

Servlet (Server Applet) 服务器小程序,主要功能用于生成动态Web内容

Servlet是J2EE最重要的组成部分

Web与 Servlet的关系:

获取请求参数(来自HTML的数据输入)

(1) request.getParameter() 取得是通过容器的实现来取得通过类似post,get等方式传入的数据
request.setAttribute()[往域中保存数据] 和 getAttribute()[从域中获取数据]只是在web容器内部流转,仅仅是请求处理阶段。
(2) request.getParameter () 方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。
原文链接:https://blog.csdn.net/qq_54000767/article/details/128003181ContentType
(3) String getParameter(String name) 根据请求参数名获取请求参数值
(4) String[] getParameterValues(String name) 根据请求参数名获取请求参数多个值
(5) Enumeration getParameterNames() 获取所有的请求参数名
(6) Map<String, String[]> getParameterMap() 获取所有请求擦桉树 把请求参数保存到map集合
(7) req.getServletContext() 实质上可以看做一个对象,其可以使用ServletContext接口中的方法

1.在javax.servlet.Filter中直接获取 ServletContext context = config.getServletContext();
2.在HttpServlet中直接获取 this.getServletContext()
3.在其他方法中,通过HttpRequest获得 request.getSession().getServletContext();

(8) getRequestDispatcher() getRequestDispatcher()包含两个重要方法
分别是请求转发和请求包含。一个请求跨多个Servlet时,需要使用请求转发和请求包含。
首先需要获得一个RequestDispatcher 对象:RequestDispatcher rd = request.getRequestDispatcher(“/MyServlet”);

  • request.getRequestDispatcher().forward() - 请求转发[请求自发器]
    请求转发是服务器跳转,指挥产生一次请求
  • response.sendRedirect() - 响应重定向
    响应重定向是浏览器端跳转,会产生两次请求
  • request.setAttribute(属性名,属性值) - 设置请求属性
    Object attr = request.getAttribute(属性名) - 获取请求属性
    请求允许创建自定义属性

决定浏览器采用何种方式对响应体进行处理
response.setContentType(“text/html; charset=utf-8”);

========FirstServlet.java========
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class FirstServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name"); //接收请求发来的参数
        String html = "<h1 style = 'color : red'>hi," + name + "!</h1><hr/>";
        System.out.println("返回給浏览器的响应数据为:" + html);
        PrintWriter out = response.getWriter();
        out.println(html);//将html发送回浏览器
    }
}
======================web.xml===============================
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <display-name>FirstServlet</display-name>
    <servlet> //servlet的别名
        <servlet-name>first</servlet-name>
        <servlet-class>FirstServlet</servlet-class>
    </servlet>
    <servlet-mapping> //映射 web应用程序都是网址来运用 把servlet和网址(url)绑定在一起
        <servlet-name>first</servlet-name>//输入地址.../hi 再通过别名来访问FirstServlet
        <url-pattern>/hi</url-pattern>//若是直接写会暴露系统类名完整信息的隐私
        <!--http://localhost:8080/Test_Tomcat_war_exploded/hi?name=jackson-->
    </servlet-mapping>
</web-app>
HttpServlet 是所有小程序的父类,需要继承 (Eclipse 快速导包 Ctrl + Shift + O)

启动项目:Servers右键Tomcat - Add and Remove

Servlet开发步骤

  • 创建Servlet类,继承HTTPServlet
  • 重写service方法,编写程序代码
  • 配置web.xml,绑定URL

Servlet访问方法

  • http:// IP地址:端口 / context-path / url-mapping
  • 远程访问使用IP地址,本地访问localhost(127.0.0.1)
  • context-path成为”上下文路径”,默认为工程名
☆ web.xml ☆
  <servlet>
      <servlet-name>sample</servlet-name>
      <servlet-class>com.imooc.servlet.SampleServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
      <servlet-name>sample</servlet-name>
      <url-pattern>/sample</url-pattern>
  </servlet-mapping>
============================================
 ☆ SampleServlet.java ☆
package com.imooc.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SampleServlet extends HttpServlet {
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter out = response.getWriter(); //向浏览器输出的数据流
        out.println("<a href='http://www.baidu.com'>Baidu</a>");
    }
}

请求参数

  • 请求参数是指浏览器通过请求向Tomcat提交的数据
  • 请求参数通常是用户输入的数据,待Servlet进行处理
  • 参数名1 = 值1 & 参数名2 = 值2 & 参数名n = …

Servlet接收请求参数

  • request.getParameter() – 接收单个参数
  • request.getParameterValues() – 接收多个同名参数
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ SampleServlet.java ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
package com.imooc.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SampleServlet extends HttpServlet {
//service是请求处理的核心方法,无论是get或者post都会被service()方法处理
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name");
        String mobile = request.getParameter("mobile");
        String sex = request.getParameter("sex");
        String[] specs = request.getParameterValues("spec");
        PrintWriter out = response.getWriter(); //向浏览器输出的数据流
        out.println("<h1>name:" + name + "</h1>");
        out.println("<h1>mobile:" + mobile + "</h1>");
        out.println("<h1>sex:" + sex + "</h1>");
        for(int i = 0; i < specs.length; i++) {
            out.println("<h2>spec:" + specs[i] + "</h2>");
        }
        out.println("<a href='http://www.baidu.com'>Baidu</a>");
    }
}
 ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ studnet.html ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学员信息登记表</title>
</head>
<body>
    <h1>学员信息登记表</h1>
    <form action="http://localhost:8080/Test_Tomcat_war_exploded/sample" method="get" >
        姓名:<input name="name"/>
        <br/>
        电话:<input name="mobile"/>
        <br/>
        性别:
        <select name="sex" style="width:100px;padding:5px;">
            <option value="male" >男</option>
            <option value="female">女</option>
        </select>
        <br/>
        特长:
        <input type="checkbox" name="spec" value="English"/>英语
        <input type="checkbox" name="spec" value="Program"/>编程
        <input type="checkbox" name="spec" value="Speech"/>演讲
        <input type="checkbox" name="spec" value="Swimming"/>游泳
        <br/>
        <input type="submit" value="提交">
        <br/>
    </form>
</body>
</html>

Get与Post请求方法

  • Get方式(可读性好) 是将数据通过在URL附加数据显性向服务器发送数据[明文] Get请求 - doGet()方法

http:// localhost:8080/Test_Tomcat_war_exploded/sample?name = zhangsan

  • Post方式(更加隐蔽) 会将数据存放在“请求体”中隐性向服务器发送数据[隐性请求体] Post请求 - doPost()方法

http:// localhost:8080/Test_Tomcat_war_exploded/sample

请求体:name=zhangsan

所有请求 - service()方法

☆ ☆ ☆ ☆ ☆ ☆ Get与Post请求方法 ☆ ☆ ☆ ☆ ☆ ☆

#### Get与Post处理方式

- 所有请求-service()方法
- Get请求-doGet()方法
- Post请求-doPost()方法

#### Get与Post应用场景

- Get常用于不包含敏感信息的查询功能
- Post用于安全性要求较高的功能或者服务器的“写”操作
  - 用户登录
  - 用户注册
  - 更新公司账目
    
HTML默认以get方式提交,可以改变方式
<form action="http://localhost:8080/Test_Tomcat_war_exploded/sample" 
    method="post" 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RequestMethodServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name");
        response.getWriter().println("<h1 style = 'color:green'>"+name+"</h1>");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name");
        response.getWriter().println("<h1 style = 'color:red'>"+name+"</h1>");
    }
}

Servlet生命周期

  • 装载 - web.xml

  • 创建 - 构造函数

    public FirstServlet(){
    System.out.println(“正在创建FirstServlet对象”);
    }

  • **初始化 - init() **[启动时加载 类似于LOL入场进度条]

    @Override
    public void init(ServletConfig config) throws ServletException {
    System.out.println(“正在初始化FirstServlet对象”);
    }

  • 提供服务 - service()

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String name = request.getParameter(“name”); //接收请求发来的参数
    String html = “

    hi,” + name + “!


    “;
    System.out.println(“返回給浏览器的响应数据为:” + html);
    PrintWriter out = response.getWriter();
    out.println(html);//将html发送回浏览器
    }

  • 销毁 - destroy() [重启的时候会施行销毁]

    @Override
    public void destroy() {
    System.out.println(“正在销毁FirstServlet对象”);
    }

使用注解简化配置

  • Servlet 3.x 之后引入了“注解Annotation”特性
  • 注解用于简化web应用程序的配置过程
  • Servlet核心注解:**@WebServlet** [简化配置 以防.xml的依赖越来越多]
    @WebServlet(“/anno”) 把servlet类绑定到/anno

设置loadOnStartup后必须要强制设置地址

@WebServlet(urlPatterns=”/unused”, loadOnStartup=2)

@WebServlet("/anno")
public class AnnotationServlet extends HttpServlet{}
AnnotationServlet是Servlet类把它绑定到标志("/anno")上

//http://localhost:8080/Test_Tomcat_war_exploded/anno

启动时加载Servlet [模仿开发项目场景]

  • web.xml使用< load-on-startup >设置启动加载
  • < load-on-startup > 0~9999 < /load-on-startup >
    为加载顺序 0的优先级最高
  • 启动时加载在工作中常用于系统的预处理

CreateServlet.java

package com.imooc.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class CreatServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("正在创建数据库");
    }
}

ImportServlet.java

package com.imooc.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class ImportServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("正在导入数据");
    }
}

AnalysisServlet.java

package com.imooc.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class AnalysisServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("正在分析结果");
    }
}

web.xml

< url-pattern > /hi < /url-pattern >提供服务时才会写
因为这三个servlet只是启动的时候运行 不提供服务不用写url

<servlet>
    <servlet-name>create</servlet-name>
    <servlet-class>com.imooc.servlet.CreatServlet</servlet-class>
    <load-on-startup>0</load-on-startup> //在启动时最先被加载
</servlet>
<servlet>
    <servlet-name>import</servlet-name>
    <servlet-class>com.imooc.servlet.ImportServlet</servlet-class>
    <load-on-startup>1</load-on-startup> 
</servlet>
<servlet>
    <servlet-name>analysis</servlet-name>
    <servlet-class>com.imooc.servlet.AnalysisServlet</servlet-class>
    <load-on-startup>2</load-on-startup> 
</servlet>
若是不写入xml则需要注解@WebServlet
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
@WebServlet(urlPatterns = "/unused", loadOnStartup = 1)
public class ImportServlet1 extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("正在导入数据1");
    }
}

其中必须@WebServlet(urlPatterns = “/unused”, loadOnStartup = 1)
必须要地址url



JSP(Java Server Pages)入门

JSP是J2EE的功能模块,由Web服务器执行

JSP的作用就是降低动态网页开发难度

JSP的出现:Servlet有缺点

  • 静态HTML与动态Java代码混合在一起,难以维护
  • Servlet利用out.println()语句输出,开发效率低下
  • Eclipse很难在开发中发现错误,调试困难

JSP特点
①.使用简单, 短时间学习便可上手使用
②.可将Java代码与HTML分离, 降低开发难度
③.JSP的本质就是Servlet

JSP中的写java代码块 <% … %>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Insert title here</title>
</head>
<body>
<table>
  <tr>
    <th>year</th>
    <th>salary</th>
  </tr>
  <%
    for (int i = 0; i <= 50; i++){
      out.println("<tr>");
      out.println("<td>" + i + "</td>");
      int sal = 0;
      if (i <= 5){
        sal = 1500 + i * 150;
      } else if (i > 5 && i <= 10) {
        sal = 1500 + 150 * 5 + 300 * (i-5);
      } else if (i > 10) {
        sal = 1500 + 150 * 5 + 300 * 5 + 375 * (i-10);
      }
      out.println("<td>" + sal + "</td>");
      out.println("</tr>");
    }
  %>
</table>
</body>
</html>

JSP的执行过程

网页通过JSP(Tomcat) 进行转译成为Servlet源代码 然后编译Servlet字节码 最后返回到网页呈现

JSP的基本语法

JSP代码块

JSP代码块用于JSP中嵌入Java代码
JSP代码块语法:<% java代码 %>

JSP声明构造块

JSP声明构造块用于声明变量或方法
JSP声明构造块语法:<%! 声明语句 %>

JSP输出指令

JSP输出指令用于在JSP页面中显示java代码执行结果
JSP输出指令语法:<%= java代码 %>
例如:<%= “< b >” + name + “< /b >” %>

JSP处理指令

JSP处理指令用于提供JSP执行过程中的辅助信息
JSP处理指令语法:<%@ jsp指令 %>
例如:<%@ page import = “java.util.*” %>

JSP常用处理指令

<%@ page %> 定义当前JSP页面全局设置
<%@ include file = “url…”%> 将其他JSP页面与当前JSP页面合并
<%@ taglib %> 引入JSP标签库

JSP中注释的区别

<%– 注释 –%> JSP注释,被注释语句不做任何处理
//、/../ 用于注释<% %>java代码,被注释代码不执行
< !– html – > HTML注释,被注释的语句不会被浏览器解释

综合训练:质数算法

列出1000内的质数(除1以外,只能被1和自身整除的自然数)

要求1:使用List保存所有有效的质数
要求2:将结果打印到页面,格式为”< h1 > X是质数 < /h1 >”

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%!
    boolean isPrime(int num){
        boolean flag = true;
        for (int j = 2; j < num; j++) {
            if (num % j ==0){
                flag = false;
                break;
            }
        }
        return flag;
    }
%>
<%
    List<Integer> primes = new ArrayList();
    for (int i = 2; i <= 1000; i++){
        boolean flag = isPrime(i);
        if (flag == true){
//        out.println("<h1>" + i + "</h1>");
            primes.add(i);
        }
    }
%>
<%
    for (int p : primes){
//        out.println("<h1>" + p + "是质数</h1>");
%>
    <h1 style="color: green"><%=p %>是质数</h1>
<%
    }
%>

JSP页面重用

<%@ include file = “url…”%> 将其他JSP页面与当前JSP页面合并

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ news.jsp ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="include/header.jsp"%>
<%
  out.println("<h1>新闻标题</h1>");
  out.println("<p>新闻正文</p>");
%>
<%@include file="include/footer.jsp"%>

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ header.jsp ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
体育|推荐|财经|娱乐

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ footer.jsp ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<hr/>
Copyright 1999-2023

JSP&Servlet进阶

HTTP请求的结构

  • HTTP请求包含三部分:请求行、请求头、请求体

eclipse导入jar包 (工程名 - Properties - Java Build Path - Libraries - Add EXternal JARs)
查看F12网络 - All 可查看内部详细信息常规
input.html

get请求把数据放在url中 post请求把数据放在请求体中

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>                  <!-- 工程名 + 映射地址 -->
    <form action="/request-struc/request" method="post">
        <input name="username"/>
        <input name="password" type="password"/>
        <input type="submit"/>
    </form>
</body>
</html>

巧用请求头开发多端应用

根据请求头去对应不同的设备
同样的网址在手机电脑上所呈现的内容是不一样的

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/ua")
public class UserAgentServlet extends HttpServlet {
    public UserAgentServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userAgent = req.getHeader("User-Agent");
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().println(userAgent);
        String output = "";
        if (userAgent.indexOf("Windows NT")!=-1){
            output = "<h1>这是PC端首页</h1>";
        } else if (userAgent.indexOf("iPhone")!=-1 || userAgent.indexOf("Android")!=-1) {
            output = "<h1>这是移动端首页</h1>";
        }
        resp.getWriter().println(output);
    }
}

响应的结构 (服务器返回給浏览器的显示结果)

HTTP请求包含三部分:响应行、响应头、响应体

状态码 错误描述
200 服务器处理成功
404 无法找到文件
500 内部服务器错误
403 服务器拒绝访问
301、302 请求重定向
400 无效的请求
401 未经过授权
503 服务器超负载或正停机维护,无法处理请求

ContentType的作用

ContentType决定浏览器采用何种方式对响应体进行处理

response.setContentType(“text/html; charset=utf-8”);

MIME类型 描述
text/plain 纯文本
text/html HTML文档
text/xml XML文档
application/x-msdownload 需要下载的资源
image/jpeg
image/gif
image/…
图片资源
protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        String output = "<h1><a href='http://www.baidu.com'><span>百度</span></a></h1>";
        response.setContentType("text/html; charset=utf-8");
        response.getWriter().println(output);
    }

请求转发与重定向 [二次跳转与定位]

多个Servlet(JSP)之间跳转有两种方式:

  • request.getRequestDispatcher().forward() - 请求转发[请求自发器]
    请求转发是服务器跳转,指挥产生一次请求
  • response.sendRedirect() - 响应重定向
    响应重定向是浏览器端跳转,会产生两次请求
  • request.setAttribute(属性名,属性值) - 设置请求属性
    Object attr = request.getAttribute(属性名) - 获取请求属性
    请求允许创建自定义属性

CheckLoginServlet.java
package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
    public CheckLoginServlet() {
    }

    @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("用户登录成功");
        //创建自定义属性
        req.setAttribute("username","admin");

        //实现了请求转发的功能[从服务器内部由第一个servlet转到第二个] forward(请求 + 响应)
        req.getRequestDispatcher("/direct/index").forward(req, resp);
        //响应重定向需要增加contextPath[将请求第一次处理完后将响应重新发送一个新的请求給index servlet]
        resp.sendRedirect("/direct/index"); //[结果已被重定向]
    }
}
==============================================================
indexServlet.java
package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/direct/index")
public class indexServlet extends HttpServlet {
    public indexServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收创建的自定义属性
        String username = (String)req.getAttribute("username");
        resp.getWriter().println("This is index page!current username is " + username);
    }
}

浏览器Cookie [浏览器重启但用户登录不会消失]

  • Cookie是浏览器保存在本地的文本内容
  • Cookie常用于保存登录状态、用户资料等小文本
  • Cookie具有时效性,Cookie内容会伴随请求发送給Tomcat
  • request.getCookies() 用户获取所有的Cookie
  • cookie.setMaxAge() 用户设置cookie保存的时间(单位:秒s)
ImoocLoginServlet.java
package cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/cookies/login")
public class ImoocLoginServlet extends HttpServlet {
    public ImoocLoginServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("用户登录成功");
        Cookie cookie = new Cookie("user","admin");
        cookie.setMaxAge(60 * 60 * 24 * 7); //单位是秒 七天内有效
        resp.addCookie(cookie);
        resp.getWriter().println("login success");
    }
}

================================================================
ImoocIndexServlet.java
package cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/cookies/index")
public class ImoocIndexServlet extends HttpServlet {
    public ImoocIndexServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cs = req.getCookies();
        String user = null;
        for (Cookie c : cs){
            System.out.println(c.getName() + ":" + c.getValue());
            if (c.getName().equals("user")){
                user = c.getValue();
                break;
            }
        }
        if (user == null){
            resp.getWriter().println("user not login");
        }else {
            resp.getWriter().println("user:" + user);
        }
    }
}

Session-用户会话

  • Session(用户会话) 用于保存与 ”浏览器窗口“ 对应的数据
  • Session的数据存储在Tomcat服务器的内存中,具有时效性
  • Session通过浏览器Cookie的SessionId值提取用户数据

Session类似于是浏览器单独存储的空间,每个浏览器窗口所对应的Session空间是不同的;
Session是与浏览器窗口绑定的且把数据存储在Tomcat内存中的对象

SessionLoginServlet.java
package session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/session/login")
public class SessionLoginServlet extends HttpServlet {
    public SessionLoginServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("用户登录成功");
        //获取到用户会话Session对象
        HttpSession session = req.getSession();
        String sessionId = session.getId(); //A99EA3178EDC7C490E29D8EC46930FC6
        System.out.println(sessionId);
        session.setAttribute("name","张三");
        req.getRequestDispatcher("/session/index").forward(req,resp); //请求转发
    }
}
============================================================================
SessionIndexServlet.java
package session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/session/index")
public class SessionIndexServlet extends HttpServlet {
    public SessionIndexServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        String sessionId = session.getId(); //A99EA3178EDC7C490E29D8EC46930FC6
        System.out.println(sessionId);
        String name = (String)session.getAttribute("name");
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("这是首页,当前用户为: " + name);
    }
}

区别:
cookie数据保存在客户端,session数据保存在服务端。

session
简单的说,当你登陆一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话session_id,服务器根据当前session_id判断相应的用户数据标志,以确定用户是否登陆或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造。

cookie
session_id是服务器和客户端连接时候随机分配的,如果浏览器使用的是cookie,那么所有数据都保存在浏览器端,比如你登陆以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。

如果你能够截获某个用户的cookie变量,然后伪造一个数据包发送过去,那么服务器还是 认为你是合法的。所以,使用cookie被攻击的可能性比较大。

如果cookie设置了有效值,那么cookie会保存到客户端的硬盘上,下次在访问网站的时候,浏览器先检查有没有cookie,如果有的话,读取cookie,然后发送给服务器。

所以你在机器上面保存了某个论坛cookie,有效期是一年,如果有人入侵你的机器,将你的cookie拷走,放在他机器下面,那么他登陆该网站的时候就是用你的身份登陆的。当然,伪造的时候需要注意,直接copy cookie文件到 cookie目录,浏览器是不认的,他有一个index.dat文件,存储了 cookie文件的建立时间,以及是否有修改,所以你必须先要有该网站的 cookie文件,并且要从保证时间上骗过浏览器

两个都可以用来存私密的东西,session过期与否,取决于服务器的设定cookie过期与否,可以在cookie生成的时候设置进去

四、区别对比:
(1) cookie数据存放在客户的浏览器上,session数据放在服务器上
(2) cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session
(3) session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
(4) 单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。
(5) 所以:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中

ServletContext

  • ServletContext(Servlet上下文对象),是Web应用全局对象
  • 一个Web应用只会创建一个ServletContext对象
  • ServletContext随着Web应用启动而自动创建

如果是session 则关闭一次浏览器sessionId就会发生变化 重新加载session
只要设置了自定义属性就会在全局生效

Java Web三大作用域对象 [作用域生命周期依次递增]

  • HttpServletRequest - 请求对象
    [网页请求 Tomcat响应一次后销毁]
  • HttpSession - 用户会话对象
    [保存与浏览器窗口的数据 网页请求 Tomcat响应后有30分钟没有被访问则销毁]
  • ServletContext - web应用全局对象
    [Web启动时被创建]

能用小作用域完成开发的功能就尽量不要使用大作用域

Web应用的中文乱码由来

  • Tomcat默认使用字符集ISO-8859-1,属于西欧字符集
  • 解决乱码的核心思路是将ISO-8859-1转换为UTF-8
  • Servlet中请求与响应都需要设置UTF-8字符集
Ⅰ.麻烦且不实用
String utf8Ename = new String(ename.getBytes("iso-8859-1"), "utf-8");
String utf8EAddress = new String(address.getBytes("iso-8859-1"), "utf-8");

Ⅱ.简便且实用 
写在★★doPost★★下面的第一行
request.setCharacterEncoding("UTF-8");
//对于Tomocat8.x的版本, 默认get请求发送中文就是UTF-8, 因此无需转换
写在★★doGet★★下面
response.setContentType("text/html;charset=utf-8");

web.xml常用配置

  • 修改web应用默认首页
  • Servlet通配符映射及初始化参数
  • 设置404、500等状态码默认页面
设置默认首页地址 => 在web.xml中 设置
设置后启动tomcat后自动弹出首页为student.html中的内容
<welcome-file-list>
  <welcome-file>student.html</welcome-file>
</welcome-file-list>
根目录/二级页面也可以查找默认首页

模糊匹配:* [Servlet通配符]

@WebServlet(“/cookies/*”)

☆ ☆ ☆ ☆ web.xml ☆ ☆ ☆ ☆
<servlet>
 <servlet-name>patternServlet</servlet-name>
 <servlet-class>PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name>patternServlet</servlet-name>
 <url-pattern>/pattern/*</url-pattern>
</servlet-mapping>
☆ ☆ ☆ ☆ PatternServlet.java ☆ ☆ ☆ ☆
public class PatternServlet extends HttpServlet{
    @Override
    protected void service(HttpServletRequest request,HttpServletReasponse reasponse){
        //查询员工的基本信息 获取当前访问的URL
        String url = request.getRequestURL().toString();
        System.out.println(url);
        String id = url.substring(url.lastIndexOf("/") + 1);
        int eid =  Integer.parseInt(id);
        response.setContentType("text/html;charest=utf-8");
        PrintWriter out = response.getWriter();
        out.println(id);
        if(eid == 1) {
            out.println("张三");
        }else if(eid == 2) {
            out.println("李四");
        }else {
            out.println("其他员工");
        }
    }
}

全局配置

这样做以后就可以直接修改xml里面的东西就好了
<context-param>
 <param-name>copyright</param-name>
 <param-value>@ 2023 imooc.com 京ICP备 12003892号-22</param-value>
</context-param>
<context-param>
 <param-name>title</param-name>
 <param-value>慕课网-程序员的梦工厂</param-value>
</context-param>
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
    public ServletContextInitServlet() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = request.getServletContext();
        String copyright = context.getInitParameter("copyright");
        context.setAttribute("copyright", copyright);
        String title = context.getInitParameter("title");
        context.setAttribute("title", title);
        response.getWriter().println("init success");
    }
}

针对404、500出现透露信息的bug处理方式

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ 404.html ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>Insert title here</title>    
</head>
<body>
    资源不存在   
</body>
</html>

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ 500.html ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>Insert title here</title>    
</head>
<body>
    服务器内部错误,请联系管理员  
</body>
</html>

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ web.xml ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
<!-- 指定错误页面 -->
<error-page>
 <error-code>404</error-code>
 <location>/error/404.html</location>
</error-page>
<error-page>
 <error-code>500</error-code>
 <location>/error/500.html</location>
</error-page>
======================================================================
可以把404\500.html随时转换成 404\500.jsp
仅需在顶加上<%@ page contentType="text/html;charset=utf-8" isErrorPage="true"%>
isErrorPage="true" 说明此jsp专门用于错误页面

<%@ page contentType="text/html;charset=utf-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>Insert title here</title>    
</head>
<body>
    服务器内部错误,请联系管理员,错误信息如下:
    <%
        String msg = exception.getMessage();
        out.print("<br>" + exception.getClass().getSimpleName() + ":" + msg);
        <!--  NumberFormatException:For input String:""  -->
    %>
</body>
</html>

JSP九大内置对象[面试/笔试重点]

内置对象 描述
request 请求对象 -HttpServletRequest
response 响应对象 -HttpServletResponse
session 用户会话 -HttpSession
application 应用全局对象 -ServletContext
out 输出对象 -PrintWriter
page 当前页面对象 -this
pageContext 页面上下文对象 -PageContext
config 应用配置对象 -ServletConfig
exception 应用异常对象 -Throwable
<body> <!--内置了许多java的类-->
    <%
        String url = request.getRequesrURL().toString(); //HttpServletRequest
        response.getWriter().println(url); //HttpServletResponse
    %>
    <%
        out.println("<br>ABCCC");
        session.setAttribute("user","张三");
        out.println((String)session.getAttribute("user"));
    %>
    <%
        String cp = application.getInitParameter("copyright"); //ServletContext
        out.println("<hr/>");
        out.println(cp); 
        pageContext.getRequest(); //pageContext就像一个中转站
           pageContext.getResponse();
        pageContext.getSession();
        pageContext.getServletContext();
    %>
</body>

Java Web打包与发布

  • Java Web应用采用war包进行发布
  • 发布路径为:{TOMCAT_HOME}/webapps
  • Eclipse支持war包导出

IDEA怎么把web项目打成war包最详细图文教程_idea web项目打成war包_Keeling1720的博客-CSDN博客
IDEA 将项目打包war包_虚拟机安装tomcat_dadeity的博客-CSDN博客

EL(Expression Language)表达式

${student.name} => [自定义属性名. 子属性]

  • EL表达式用于简化JSP的输出
  • EL表达式的基本语法:**${表达式}**
  • 示例:< h1 >学生姓名:**$(student.name)** < /h1 >
StudentServlet.java
protected void doGet(...){
    Student stu = new Student();
    stu.setName("子墨");
    stu.setMobile(null);
    String grade = "A";
    request.setAttribute("student",stu);
    request.setAttribute("grade",grade);
    request.getRequestDispatcher("/info.jsp").forward(request, response);

}
☆ ☆ ☆ ☆ ☆ ☆ info.jsp ☆ ☆ ☆ ☆ ☆ ☆
<body>
    <% 
        Student stu = (Student)request.getAttribute("student");
           Student grade = (Student)request.getAttribute("grade");
        out.println("姓名:"+ stu.getName())
        out.println("姓名:"+ stu.getMobile())
        out.println("姓名:"+ grade)
    %>
</body>
☆ ☆ ☆ ☆ ☆ ☆ el_info.jsp ☆ ☆ ☆ ☆ ☆ ☆
<body>
    姓名: ${requestScope.student.name}
    手机: ${requestScope.student.mobile}
    评级: ${requestScope.grade}
</body>

作用域对象

  • requestScope是EL作用域对象
  • EL表达式内置四种作用域对象
  • 忽略书写作用域对象时,el则按作用域从小到大一次尝试获取
作用域对象 描述
pageScope 从当前页面取值
requestScope 从当前请求中获取属性值
sessionScope 从当前会话中获取属性值
applicationScope 从当前应用获取全局属性值

姓名: ${requestScope.student.name} 其中的requestScope可以省略 el则按作用域从小到大一次尝试获取

EL表达式输出 [支持运算]

  • 语法:${[作用域.]属性名[.子属性]}
  • EL表达式支持对运算结果进行输出
  • EL支持绝大多数对象输出,本质是执行toString()方法
${title}
${requestScope.student.name}
${emp.salary + 300}
${1<=3 && 2>4}

EL输出参数值

  • EL表达式内置param对象来简化参数的输出
  • 语法: ${param.参数名}
☆ ☆ ☆ ☆ ☆ ☆ el_info.jsp ☆ ☆ ☆ ☆ ☆ ☆
<body>
    姓名: ${param.student.name}
    手机: ${param.student.mobile}
    评级: ${param.grade}
</body>

JSTL(JSP Standard Tag Libarary) 标签库

  • JSTL用于简化JSP开发,提高代码的可读性与可维护性
  • JSTL由SUN(Oracle)定义规范,由Apache Tomcat团队实现

安装JSTL标签库

  • 将Jar文件复制到工程的 /WEB-INF/lib 目录
  • 将Jar文件复制到Tomcat安装目录的lib目录
标签 描述
< c:out > 用于在JSP中显示数据,就像<%= … >
< c:set > 用于保存数据
< c:remove > 用于删除数据
< c:catch > 用来处理产生错误的异常状况,并且将错误信息储存起来
< c:if > 与我们在一般程序中用的if一样
< c:choose > 本身只当做<c:when>和<c:otherwise>的父标签
< c:when > <c:choose>的子标签,用来判断条件是否成立
< c:otherwise > <c:choose>的子标签,接在<c:when>标签后,当<c:when>标签判断为false时被执行
< c:import > 检索一个绝对或相对 URL,然后将其内容暴露给页面
< c:forEach > 基础迭代标签,接受多种集合类型
< c:forTokens > 根据指定的分隔符来分隔内容并迭代输出
< c:param > 用来给包含或重定向的页面传递参数
< c:redirect > 重定向至一个新的URL.
< c: 使用可选的查询参数来创造一个URL

JSTL的标签库种类

  • JSTL按功能划分可分为五类标签库
类别
核心标签库 - core
格式化输出标签库 - fmt
SQL操作标签库 - sql
XML操作标签库 - xml
函数标签库 - functions

引用JSTL核心库 [“< c:?? >”]

  • 核心标签库 - core 是JSTL最重要的标签库,提供了JSTL的基础功能
  • <%@ taglib prefix = “c” uri = “http://java.sun.com/jsp/jstl/core" %> 引入标签库

< c: ?? > … < /c:?? >
< c:out >输出

C标签c:forEach的用法
<c:forEach var="name" items="Collection" varStatus="statusName" begin="begin" end="end" step="step">/c:forEach>
该标签根据循环条件遍历集合 Collection 中的元素。 var 用于存储从集合中取出的元素;items 指定要遍历的集合;varStatus 用于存放集合中元素的信息

这个标签的目的就是要遍历

items: 就是你要遍历的集合,就是要遍历的全部内容要放在这个下面

var:  就是这个集合下面的每一个元素,比如一个集合{1,2,3,4,5},那么var表示的就是1或者2或者3...

begin: 默认从0开始,表示从第几个开始取元素

end: 和begin对应,表示到第几个元素终止

step:  步进,默认是1,表示一个一个跳,还是任意数字跳

varStatus:  表示集合中每个元素的相关信息,有4种状态:index(所在位置,即索引).count(总共已迭代的次数).first(是否为第一个位置),last(是否为最后一个位置)

request.getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型 。
1.放的时候:Double res = new Double(result);//包装
request.setAttribute(“result”, res);//再设置进去
2.取的时候:Double res = (Double)request.getAttribute(“result”);
double result = res.doublue();
另外,需要注意的是使用request.setAttribute时不能使redirect而是forward。即是将请求转发而不是重定向.

<%@ page contentType="text/html;charset=GBK" %>
<%@page import="java.util.List" %>
<%@page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>JSTL: -- forEach标签实例</title>
</head>
<body>
<h4><c:out value="forEach实例"/></h4>
<hr>
<%
    List a = new ArrayList();
    a.add("贝贝");
    a.add("晶晶");
    a.add("欢欢");
    a.add("莹莹");
    a.add("妮妮");
    request.setAttribute("a",a);
%>
<B><c:out value="不指定begin和end的迭代"/></B><br>
<c:forEach var="fuwa" items="${a}">
    &nbsp;<c:out value="${fuwa}"/><br>
</c:forEach>

<B><c:out value="指定bigin和end的迭代"/></B><br>
<c:forEach var="fuwa" items="${a}" begin="1" end="3" step="2">
    &nbsp;<c:out value="${fuwa}"/><br>
</c:forEach>

<B><c:out value="输出整个迭代信息"/></B><br>
<c:forEach var="fuwa" items="${a}" begin="3" end="4" step="1" varStatus="s">
    &nbsp;<c:out value="${fuwa}"/>的四种属性:<br>
    &nbsp;&nbsp;所在位置,即索引:<c:out value="${s.index}"/><br>
    &nbsp;&nbsp;总共已迭代的次数:<c:out value="${s.count}"/><br>
    &nbsp;&nbsp;是否为第一个位置:<c:out value="${s.first}"/><br>
    &nbsp;&nbsp;是否为最后一个位置:<c:out value="${s.last}"/><br>
</c:forEach>
</body>
</html>

forEach实例
---------------------------------------------------------
不指定begin和end的迭代
 贝贝
 晶晶
 欢欢
 莹莹
 妮妮
指定bigin和end的迭代
 晶晶
 莹莹
输出整个迭代信息
 莹莹的四种属性:
  所在位置,即索引:3
  总共已迭代的次数:1
  是否为第一个位置:true
  是否为最后一个位置:false
 妮妮的四种属性:
  所在位置,即索引:4
  总共已迭代的次数:2
  是否为第一个位置:false
  是否为最后一个位置:true

判断标签

  • JSTL核心库提供了两组判断的标签
  • < c : if > - 单分支判断
  • < c:choose >、< c:when>、< c:otherwise > - 多分支判断
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/jstl")
public class JstlServlet extends HttpServlet {
    public JstlServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("score",78);
        req.setAttribute("grade","B");
        req.getRequestDispatcher("/core.jsp").forward(req,resp);
    }
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!-- 在Java或者JSP文件中输入 Alt + / 可出现智能提示 -->
<%@ taglib  uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
<h1>${requestScope.score}</h1>
<c:if test = "${score >= 60 }">
    <h1 style = "color:green">恭喜,你已通过测试</h1>
</c:if>
<c:if test = "${score < 60 }">
    <h1 style = "color:red">对不起,再接再厉</h1>
</c:if>
</body>
</html>

遍历集合

  • < c:forEach >标签用于遍历集合(Collection)中的每一个对象

c:if 和c:when 的区别
(1)c:when必须嵌套在c:choose
(2)<c:if /> 或者 <c:if >< /c:if> <c:when > < /c:when >
(3)c:if 可以放回判断语句执行结果的值 而c:when不能
例如:<c:if test=”XXX” var=”result” />
<c:out value=”${result}”>
(4)when 可以有otherwise.相当于else. 而用if没有else配对.

<c:forEach var="p" items="${persons}" varStatus="idx">
第${idx.index + 1}位 <br/>
姓名: ${p.name} 性别: ${p.sex} 年龄:${p.age}
</c:forEach>
JstlServlet.java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/jstl")
public class JstlServlet extends HttpServlet {
    public JstlServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("score",20);
        req.setAttribute("grade","E");
        List list = new ArrayList();
        list.add(new Company("腾讯", "www.tencent.com"));
        list.add(new Company("百度", "www.baidu.com"));
        list.add(new Company("慕课网", "www.imooc.com"));
        //把list放在当前请求中
        req.setAttribute("companies", list);
        req.getRequestDispatcher("/core.jsp").forward(req,resp);
    }
}
core.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!-- 在Java或者JSP文件中输入 Alt + / 可出现智能提示 -->
<%@ taglib  uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
<h1>${requestScope.score}</h1>
<c:if test = "${score >= 60 }">
    <h1 style = "color:green">恭喜,你已通过测试</h1>
</c:if>
<c:if test = "${score < 60 }">
    <h1 style = "color:red">对不起,再接再厉</h1>
</c:if>
${grade}
<c:choose>
    <c:when test="${grade == 'A'}">
        <h2>你很优秀</h2>
    </c:when>
    <c:when test="${grade == 'B'}">
        <h2>不错哟</h2>
    </c:when>
    <c:when test="${grade == 'C'}">
        <h2>水平一般,需要提高</h2>
    </c:when>
    <c:when test="${grade == 'D'}">
        <h2>需要努力,不要气馁</h2>
    </c:when>
    <c:otherwise>
        <h2>一切随缘吧</h2>
    </c:otherwise>
</c:choose>
<!-- forEach标签用于遍历集合 
        List companys = (List)request.getAttribute("companys")
        for(Company c : companys){
            out.print("...")
        }
        idx = index
        idx.index属性代表循环的索引值(0开始)
    -->
    <c:forEach items="${requestScope.companies}" var="c">
        <h2 style="color: green">${idx.index}.${c.cname}-${c.url}</h2>
    </c:forEach>
</body>
</html>

fmt格式化标签库

  • fmt格式化标签库URl : http://java.sun.com/jsp/jstl/fmt
  • < fmt:formatDate value = “” pattern = “” > 格式化日期标签
  • < fmt:formatNumber value = “” pattern = “”> 格式化数字标签,百分比,货币。
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/jstl")
public class JstlServlet extends HttpServlet {
    public JstlServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("score",20);
        req.setAttribute("grade","E");
        List list = new ArrayList();
        list.add(new Company("腾讯", "www.tencent.com"));
        list.add(new Company("百度", "www.baidu.com"));
        list.add(new Company("慕课网", "www.imooc.com"));
        //把list放在当前请求中
        req.setAttribute("companies", list);
        req.getRequestDispatcher("/core.jsp").forward(req,resp);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    request.setAttribute("amt", 123456.789);
    request.setAttribute("now", new java.util.Date());
    request.setAttribute("html","<a href='index.html'>index</a>");
    request.setAttribute("nothing",null);
%>
<h2>${now }</h2>
<!--
    formatDate pattern
    yyyy - 四位年
    MM - 两位月
    dd - 两位日
    HH - 24小时制
    hh - 12小时制
    mm - 分钟
    ss - 秒数
    SSS - 毫秒
-->
<h2>
    <fmt:formatDate value="${requestScope.now}" pattern="yyyy年MM月dd日HH时mm分ss秒SSS毫秒"/>
</h2>
<h2>${amt}</h2>
<h2>¥<fmt:formatNumber value = "${amt}" pattern="0,000.00"></fmt:formatNumber></h2>
<h2>null默认值:<c:out value="${nothing}" default="无"></c:out></h2>
<h2><c:out value="${html}" escapeXml="true"></c:out></h2> <!--true时进行转译-->
</body>
</html>

使用IDEA写的web项目无法加载css、js或图片等文件的解决方法

  • 直接把css、js、图片等文件放在web目录下,这样就可以实现轻松访问!
  • 在web-inf目录下找到web.xml文件,添加以下代码也可以实现正常访问!
Employee.java
public class Employee {
    private Integer empno;
    private String ename;
    private String department;
    private String job;
    private Float salary;
    ......
}

CreateServlet.java
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/create")
public class CreateServlet extends HttpServlet {
    public CreateServlet() {
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String empno = req.getParameter("empno");
        String ename = req.getParameter("ename");
        String department = req.getParameter("department");
        String job = req.getParameter("job");
        String salary = req.getParameter("salary");
        System.out.println(empno);
        Employee emp = new Employee(Integer.parseInt(empno),ename,department,job,Float.parseFloat(salary));
        ServletContext context = req.getServletContext();
        List employees = (List) context.getAttribute("employees");
        employees.add(emp); //追加
        context.setAttribute("employees", employees);
        req.getRequestDispatcher("/employee.jsp").forward(req,resp);
    }
}
ListServlet.java
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/Login")
public class ListServlet extends HttpServlet {
    public ListServlet() {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        //获取对象
        ServletContext context = req.getServletContext();
        if (context.getAttribute("employees")==null) {
            List list = new ArrayList();
            Employee emp = new Employee(7731, "刘志敏", "市场部", "客户代表", 10000f);
            list.add(emp);
            list.add(new Employee(8871, "潘春尧", "研发部", "运维工程师", 80000f));
            context.setAttribute("employees", list); //把list存放进去
        }//servlet中传递值
        req.getRequestDispatcher("/employee.jsp").forward(req,resp);
    }
}
employee.jsp
<%@ page contentType="text/html;charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>员工列表</title>
    <link href="./css/bootstrap.css" type="text/css" rel="stylesheet"/>
    <script type="text/javascript" src="./js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="./js/bootstrap.js"></script>

    <style type="text/css">
        .pagination {
            margin: 0px
        }

        .pagination > li > a, .pagination > li > span {
            margin: 0 5px;
            border: 1px solid #dddddd;
        }

        .glyphicon {
            margin-right: 3px;
        }

        .form-control[readonly] {
            cursor: pointer;
            background-color: white;
        }
        #dlgPhoto .modal-body{
            text-align: center;
        }
        .preview{

            max-width: 500px;
        }
    </style>
    <script>
        $(function () {
            
            $("#btnAdd").click(function () {
                $('#dlgForm').modal()
            });
        })
    </script>
</head>
<body>

<div class="container">
    <div class="row">
        <h1 style="text-align: center">IMOOC员工信息表</h1>
        <div class="panel panel-default">
            <div class="clearfix panel-heading ">
                <div class="input-group" style="width: 500px;">
                    <button class="btn btn-primary" id="btnAdd"><span class="glyphicon glyphicon-zoom-in"></span>新增
                    </button>
                </div>
            </div>

            <table class="table table-bordered table-hover">
                <thead>
                <tr>
                    <th>序号</th>
                    <th>员工编号</th>
                    <th>姓名</th>
                    <th>部门</th>
                    <th>职务</th>
                    <th>工资</th>
                    <th>&nbsp;</th>
                </tr>
                </thead>
                <tbody>
                <c:forEach items="${applicationScope.employees}" var="emp" varStatus="idx">
                <tr>
                    <td>${idx.index + 1}</td>
                    <td>${emp.empno}</td>
                    <td>${emp.ename}</td>
                    <td>${emp.department}</td>
                    <td>${emp.job}</td>
                    <td style="color: red;font-weight: bold">¥<fmt:formatNumber value="${emp.salary}" pattern="0,000.00"></fmt:formatNumber></td>
                </tr>
                </c:forEach>
                <tr>
                    <td>3</td>
                    <td>7839</td>
                    <td>张丽</td>
                    <td>研发部</td>
                    <td>运维工程师</td>
                    <td style="color: red;font-weight: bold">¥8,820.00</td>
                    
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

<!-- 表单 -->
<div class="modal fade" tabindex="-1" role="dialog" id="dlgForm">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">新增员工</h4>
            </div>
            <div class="modal-body">
                <form action="/untitled_war_exploded/create" method="post" >
                    <div class="form-group">
                        <label for="empno">员工编号</label>
                        <input type="text" name="empno" class="form-control" id="empno" placeholder="请输入员工编号">
                    </div>
                    <div class="form-group">
                        <label for="ename">员工姓名</label>
                        <input type="text" name="ename" class="form-control" id="ename" placeholder="请输入员工姓名">
                    </div>
                    <div class="form-group">
                        <label>部门</label>
                        <select id="dname" name="department" class="form-control">
                            <option selected="selected">请选择部门</option>
                            <option value="市场部">市场部</option>
                            <option value="研发部">研发部</option>
                            <option value="后勤部">后勤部</option>
                        </select>
                    </div>

                    <div class="form-group">
                        <label>职务</label>
                        <input type="text" name="job" class="form-control" id="sal" placeholder="请输入职务">
                    </div>

                    <div class="form-group">
                        <label for="sal">工资</label>
                        <input type="text" name="salary" class="form-control" id="sal" placeholder="请输入工资">
                    </div>

                    <div class="form-group" style="text-align: center;">
                        <button type="submit" class="btn btn-primary">保存</button>
                    </div>
                </form>
            </div>

        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
</html>